package com.cdp.web.controller.system.fileController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cdp.common.core.domain.AjaxResult;
import com.cdp.common.core.domain.entity.SysFileAudit;
import com.cdp.common.core.domain.entity.SysMechanicalPerformance;
import com.cdp.common.core.domain.entity.SysSlump;
import com.cdp.common.utils.poi.ExcelUtil;
import com.cdp.common.utils.uuid.IdUtils;
import com.cdp.system.dto.SaveDataDTO;
import com.cdp.system.service.ISysFileAuditService;
import com.cdp.system.service.ISysMechanicalPerformanceService;
import com.cdp.system.service.ISysMineralPowderService;
import com.cdp.system.service.ISysSlumpService;
import com.cdp.system.vo.CementVO;
import com.cdp.system.vo.MechanicalPerformanceVO;
import com.cdp.system.vo.SlumpVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/excel")
public class ExcelDataController {

    @Autowired
    private ISysFileAuditService fileAuditService;
    @Autowired
    private ISysMechanicalPerformanceService sysMechanicalPerformanceService;



    @Autowired
    private ISysSlumpService sysSlumpService;


    @Value("${file.excel-mechanical-performance}")
    private String mechanicalPerformanceExcelPath;

    /**
     * 格式校验测试
     */

    @PostMapping("/save/text")
    public AjaxResult saveDataText(@RequestBody SaveDataDTO saveDataDTO) {
        List<List<String>> data = saveDataDTO.getData();
        // 校验 data 中每个元素的格式
        for (List<String> item : data) {

            System.out.println("我是data的数据" + item);
            //数量检查
            if (item == null || item.size() != 3) {
                return AjaxResult.error("每条数据必须包含3个元素");

            }

            // 对第二个元素进行检查是否为有效的数字（阿拉伯数字或带小数点）
            String level2 = item.get(1);
            if (level2 == null || level2.trim().isEmpty()) {
                return AjaxResult.error("第二个元素不应为空或仅包含空白字符");
            }
            // 正则表达式解释：
            // ^-? 表示可选的负号
            // \d* 表示零个或多个数字
            // (\.\d+)? 表示可选的小数部分，以小数点开头后跟一个或多个数字
            // $ 表示字符串结束
            if (!level2.matches("^-?\\d*(\\.\\d+)?$")) {
                return AjaxResult.error("第二个元素应为有效的数字（可以是阿拉伯数字或带小数点）！");
            }

        }

        return AjaxResult.success(data);


    }


    /**
     * json文件存到服务器
     *
     * @param saveDataDTO
     * @return
     */
    @PostMapping("/save")
    public AjaxResult saveData(@RequestBody SaveDataDTO saveDataDTO) {
        try {
            return fileAuditService.processAndSaveData(saveDataDTO);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("保存失败：" + e.getMessage());
        }
    }









    /**
     * 生成力学性能excel
     */

    @PostMapping("makeExcelMechanicalPerformance")
    public AjaxResult makeExcelMechanicalPerformance() {
        List<SysMechanicalPerformance> list = sysMechanicalPerformanceService.list();

        List<MechanicalPerformanceVO> voList = new ArrayList<>();
        for (SysMechanicalPerformance sys : list) {
            MechanicalPerformanceVO vo = new MechanicalPerformanceVO();

            BeanUtils.copyProperties(sys, vo);
            if (sys.getProductionDate() != null) {
                vo.setProductionDate(java.sql.Timestamp.valueOf(sys.getProductionDate()));
            }
            vo.setStoneCoarse20315(vo.getStoneCoarse20315());
            voList.add(vo);
        }

        UUID uuid = UUID.randomUUID();
        int hash = Math.abs(uuid.hashCode());
        int sevenDigitNumber = hash % 10000000;
        String number = String.format("%07d", sevenDigitNumber);
        String fileName = System.currentTimeMillis() + "_" + number + ".xlsx";
        String filePath = mechanicalPerformanceExcelPath + fileName;

        try {
            ExcelUtil<MechanicalPerformanceVO> util = new ExcelUtil<>(MechanicalPerformanceVO.class);
            util.exportExcelToLocalV1(voList, filePath);
            return AjaxResult.success("导出成功", filePath);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("导出失败：" + e.getMessage());
        }
    }


    /**
     * 生成坍落度excel
     */
    @PostMapping("makeExcelSysSlump")
    public AjaxResult makeExcelSysSlump() {

        List<SysSlump> list1 = sysSlumpService.list();  // 从数据库查出实体类列表
        List<SlumpVO> voList = new ArrayList<>();

        // 把 SysSlump 转成 SlumpVO
        for (SysSlump entity : list1) {
            SlumpVO vo = new SlumpVO();
            BeanUtils.copyProperties(entity, vo);

            // 如果生产日期需要转换格式，下面代码可以启用
            if (entity.getProductionDate() != null) {
                vo.setProductionDate(Date.from(entity.getProductionDate().atZone(ZoneId.systemDefault()).toInstant()));
            }


            voList.add(vo);
        }

        UUID uuid = UUID.randomUUID();
        int hash = Math.abs(uuid.hashCode());
        int sevenDigitNumber = hash % 10000000;
        String number = String.format("%07d", sevenDigitNumber);
        String fileName = System.currentTimeMillis() + "_" + number + ".xlsx";
        String filePath = mechanicalPerformanceExcelPath + fileName;

        try {
            ExcelUtil<SlumpVO> util = new ExcelUtil<>(SlumpVO.class);
            util.exportExcelToLocalV1(voList, filePath);
            return AjaxResult.success("导出成功", filePath);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("导出失败：" + e.getMessage());
        }
    }


    @PostMapping("makeExcelCombined")
    public AjaxResult makeExcelCombined() {
        // 1. 查询数据
        List<SysMechanicalPerformance> list1 = sysMechanicalPerformanceService.list();
        List<SysSlump> list2 = sysSlumpService.list();

        List<MechanicalPerformanceVO> voList1 = new ArrayList<>();
        for (SysMechanicalPerformance sys : list1) {
            MechanicalPerformanceVO vo = new MechanicalPerformanceVO();
            BeanUtils.copyProperties(sys, vo);
            if (sys.getProductionDate() != null) {
                vo.setProductionDate(java.sql.Timestamp.valueOf(sys.getProductionDate()));
            }
            voList1.add(vo);
        }

        List<SlumpVO> voList2 = new ArrayList<>();
        for (SysSlump entity : list2) {
            SlumpVO vo = new SlumpVO();
            BeanUtils.copyProperties(entity, vo);
            if (entity.getProductionDate() != null) {
                vo.setProductionDate(Date.from(entity.getProductionDate().atZone(ZoneId.systemDefault()).toInstant()));
            }
            voList2.add(vo);
        }

        // 2. 构造文件路径
        UUID uuid = UUID.randomUUID();
        int hash = Math.abs(uuid.hashCode());
        int sevenDigitNumber = hash % 10000000;
        String number = String.format("%07d", sevenDigitNumber);
        String fileName = System.currentTimeMillis() + "_" + number + ".xlsx";
        String filePath = mechanicalPerformanceExcelPath + fileName;

        // 3. 创建 workbook，并将两个 sheet 写入
        try (Workbook workbook = new XSSFWorkbook()) {
            ExcelUtil<MechanicalPerformanceVO> util1 = new ExcelUtil<>(MechanicalPerformanceVO.class);
            ExcelUtil<SlumpVO> util2 = new ExcelUtil<>(SlumpVO.class);

            util1.writeToWorkbookSheet(workbook, "力学性能", voList1);
            util2.writeToWorkbookSheet(workbook, "坍落度", voList2);

            try (FileOutputStream out = new FileOutputStream(filePath)) {
                workbook.write(out);
            }

            return AjaxResult.success("导出成功", filePath);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("导出失败：" + e.getMessage());
        }
    }


}
